﻿//+-------------------------------------------------------------------------------------------------------------------------------------------------------
//
//Description: LoadBalancerConfigurationViewModel
//Author: Aravind Ramarathinam (aravr@microsoft.com)
//Copyright © Microsoft Corporation
//Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
//You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
//
//THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, 
//INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. 
//See the Apache Version 2.0 License for specific language governing permissions and limitations under the License.
// 
//--------------------------------------------------------------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.ComponentModel;
using VmroleAuthor.Models;

namespace VmroleAuthor.ViewModels
{
    public class LoadBalancerConfigurationViewModel : ViewModelBase, IDataErrorInfo
    {
        private LoadBalancerConfiguration loadBalancerConfiguration;
        private readonly VmRoleResourceDefinitionViewModel resourceDefinitionViewModel;

        private StringParameterizableProperty configurationName;
        private StringParameterizableProperty frontEndNetwork;
        private StringParameterizableProperty portConfigName;
        private EnumParameterizableProperty protocol;
        private IntParameterizableProperty frontEndPort;
        private IntParameterizableProperty backEndPort;
        private IntParameterizableProperty probeIntervalInSeconds;
        private EnumParameterizableProperty probeProtocol;
        private IntParameterizableProperty probePort;
        private IntParameterizableProperty probeMaxRetryCount;
        private StringParameterizableProperty probeRequestPath;



        public static class PropertyNames
        {         
            public const string LoadBalancerConfigurationName = "LoadBalancerConfigurationName";
            public const string LoadBalancerFrontEndNetwork = "LoadBalancerFrontEndNetwork";
            public const string LoadBalancerPortConfigName = "LoadBalancerPortConfigName";
            public const string LoadBalancerPortConfigProtocol = "LoadBalancerPortConfigProtocol";
            public const string LoadBalancerFrontEndPort = "LoadBalancerFrontEndPort";
            public const string LoadBalancerBackEndPort = "LoadBalancerBackEndPort";
            public const string LoadBalancerProbeIntervalInSeconds = "LoadBalancerProbeIntervalInSeconds";
            public const string LoadBalancerProbeProtocol = "LoadBalancerProbeProtocol";
            public const string LoadBalancerProbePort = "LoadBalancerProbePort";
            public const string LoadBalancerProbeMaxRetryCount = "LoadBalancerProbeMaxRetryCount";
            public const string LoadBalancerProbeRequestPath = "LoadBalancerProbeRequestPath";

        }      

        /// <summary>
        /// Constructor
        /// </summary>
        public LoadBalancerConfigurationViewModel(LoadBalancerConfiguration loadBalancerConfiguration, VmRoleResourceDefinitionViewModel resourceDefinitionViewModel)
        {            
            this.loadBalancerConfiguration = loadBalancerConfiguration;
            this.resourceDefinitionViewModel = resourceDefinitionViewModel;          
        }

        public LoadBalancerConfiguration LoadBalancerConfiguration
        {
            get { return this.loadBalancerConfiguration; }            
            set
            {
                this.loadBalancerConfiguration = value;
                this.LoadBalancerConfigurationName.IsRequired = value != null;
                this.LoadBalancerConfigurationName.PropertyValue = null;
                this.LoadBalancerFrontEndNetwork.IsRequired = value != null;
                this.LoadBalancerFrontEndNetwork.PropertyValue = null;
                this.LoadBalancerPortConfigName.IsRequired = value != null;
                this.LoadBalancerPortConfigName.PropertyValue = null;
                this.LoadBalancerPortConfigProtocol.IsRequired = value != null;
                this.LoadBalancerPortConfigProtocol.PropertyValue = null;
                this.LoadBalancerFrontEndPort.IsRequired = value != null;
                this.LoadBalancerFrontEndPort.PropertyValue = null;
                this.LoadBalancerBackEndPort.IsRequired = value != null;
                this.LoadBalancerBackEndPort.PropertyValue = null;

                this.OnPropertyChanged(PropertyNames.LoadBalancerConfigurationName);
                this.OnPropertyChanged(PropertyNames.LoadBalancerFrontEndNetwork);
                this.OnPropertyChanged(PropertyNames.LoadBalancerPortConfigName);
                this.OnPropertyChanged(PropertyNames.LoadBalancerPortConfigProtocol);
                this.OnPropertyChanged(PropertyNames.LoadBalancerFrontEndPort);
                this.OnPropertyChanged(PropertyNames.LoadBalancerBackEndPort);
                this.OnPropertyChanged(PropertyNames.LoadBalancerProbeIntervalInSeconds);
                this.OnPropertyChanged(PropertyNames.LoadBalancerProbeProtocol);
                this.OnPropertyChanged(PropertyNames.LoadBalancerProbePort);
                this.OnPropertyChanged(PropertyNames.LoadBalancerProbeMaxRetryCount);
                this.OnPropertyChanged(PropertyNames.LoadBalancerProbeRequestPath);


            }
        }

        public void Cleanup()
        {
            this.LoadBalancerConfigurationName.IsRequired = false;
            this.LoadBalancerConfigurationName.Cleanup();
            this.LoadBalancerFrontEndNetwork.IsRequired = false;
            this.LoadBalancerFrontEndNetwork.Cleanup();
            this.LoadBalancerPortConfigName.IsRequired = false;
            this.LoadBalancerPortConfigName.Cleanup();
            this.LoadBalancerPortConfigProtocol.IsRequired = false;
            this.LoadBalancerPortConfigProtocol.Cleanup();
            this.LoadBalancerFrontEndPort.IsRequired = false;
            this.LoadBalancerFrontEndPort.Cleanup();
            this.LoadBalancerBackEndPort.IsRequired = false;
            this.LoadBalancerBackEndPort.Cleanup();
            this.LoadBalancerProbeEnabled = false;
        }


        public StringParameterizableProperty LoadBalancerConfigurationName
        {
            get
            {
                if (this.configurationName == null)
                {
                    Func<string> paramValueGetter = () => this.loadBalancerConfiguration != null ? this.loadBalancerConfiguration.ConfigurationName : null;
                    Action<string> paramValueSetter = delegate(string value)
                    {    
                        if (this.loadBalancerConfiguration != null)
                        {
                            this.loadBalancerConfiguration.ConfigurationName = value;                    
                        }                        
                    };
                    Func<string> autoParamNameGetter = () => ParametersViewModel.VMRolePrefix + PropertyNames.LoadBalancerConfigurationName;
                    ViewDefParamInfo viewDefParamInfo = new ViewDefParamInfo
                    {
                        ViewDefParameterType = ViewDefParameterType.String,
                        DefaultEnglishLabelText = "Load Balancer Configuration Name"                       
                    };

                    this.configurationName = new StringParameterizableProperty(
                        PropertyNames.LoadBalancerConfigurationName,
                        paramValueGetter,
                        paramValueSetter,
                        autoParamNameGetter,
                        ParameterType.String,
                        "Load Balancer Configuration Name",
                        this.resourceDefinitionViewModel.ResourceDefinitionParametersViewModel,
                        this.loadBalancerConfiguration != null,
                        viewDefParamInfo);
                }
                return this.configurationName;
            }
        }

        public StringParameterizableProperty LoadBalancerFrontEndNetwork
        {
            get
            {
                if (this.frontEndNetwork == null)
                {
                    Func<string> paramValueGetter = () => this.loadBalancerConfiguration != null ? this.loadBalancerConfiguration.FrontEndNetwork : null;
                    Action<string> paramValueSetter = delegate(string value)
                    {
                        if (this.loadBalancerConfiguration != null)
                        {
                            this.loadBalancerConfiguration.FrontEndNetwork = value;
                        }                        
                    };
                    Func<string> autoParamNameGetter = () => ParametersViewModel.VMRolePrefix + PropertyNames.LoadBalancerFrontEndNetwork;
                    ViewDefParamInfo viewDefParamInfo = new ViewDefParamInfo
                    {
                        IsRecommendedToBeParameterized = true,
                        ViewDefParameterType = ViewDefParameterType.Network,
                        DefaultEnglishLabelText = "Load balancer front end network reference"
                    };

                    this.frontEndNetwork = new StringParameterizableProperty(
                        PropertyNames.LoadBalancerFrontEndNetwork,
                        paramValueGetter,
                        paramValueSetter,
                        autoParamNameGetter,
                        ParameterType.String,
                        "Load balancer front end network reference",
                        this.resourceDefinitionViewModel.ResourceDefinitionParametersViewModel,
                        this.loadBalancerConfiguration != null,
                        viewDefParamInfo);
                }
                return this.frontEndNetwork;
            }
        }

        public StringParameterizableProperty LoadBalancerPortConfigName
        {
            get
            {
                if (this.portConfigName == null)
                {
                    Func<string> paramValueGetter = () =>
                        {
                            if (this.loadBalancerConfiguration == null)
                            {
                                return null;
                            }
                            if (this.loadBalancerConfiguration.PortConfig == null)
                            {
                                this.loadBalancerConfiguration.PortConfig = new PortConfig();
                            }
                            return this.loadBalancerConfiguration.PortConfig.Name;
                        };
                       
                    Action<string> paramValueSetter = delegate(string value)
                    {
                        if (this.loadBalancerConfiguration != null)
                        {
                            if (this.loadBalancerConfiguration.PortConfig == null)
                            {
                                this.loadBalancerConfiguration.PortConfig = new PortConfig();
                            }
                            this.loadBalancerConfiguration.PortConfig.Name = value;
                        }                       
                    };
                    Func<string> autoParamNameGetter = () => ParametersViewModel.VMRolePrefix + PropertyNames.LoadBalancerPortConfigName;
                    ViewDefParamInfo viewDefParamInfo = new ViewDefParamInfo
                    {
                        ViewDefParameterType = ViewDefParameterType.String,
                        DefaultInitialValue = "LoadBalancerPortConfig",
                        DefaultEnglishLabelText = "Load balancer port configuration name"
                    };

                    this.portConfigName = new StringParameterizableProperty(
                        PropertyNames.LoadBalancerPortConfigName,
                        paramValueGetter,
                        paramValueSetter,
                        autoParamNameGetter,
                        ParameterType.String,
                        "Load balancer port configuration name",
                        this.resourceDefinitionViewModel.ResourceDefinitionParametersViewModel,
                        this.loadBalancerConfiguration != null,
                        viewDefParamInfo);
                }
                return this.portConfigName;
            }
        }

        /// <summary>
        /// PortCfgProtocol
        /// </summary>
        public EnumParameterizableProperty LoadBalancerPortConfigProtocol
        {
            get
            {
                if (this.protocol == null)
                {                  
                    Func<string> paramValueGetter = () =>
                    {
                        if (this.loadBalancerConfiguration == null)
                        {
                            return null;
                        }
                        if (this.loadBalancerConfiguration.PortConfig == null)
                        {
                            this.loadBalancerConfiguration.PortConfig = new PortConfig();
                        }
                        return this.loadBalancerConfiguration.PortConfig.Protocol;
                    };                  
                    Action<string> paramValueSetter = delegate(string value)
                        {
                            if (this.loadBalancerConfiguration != null)
                            {
                                if (this.loadBalancerConfiguration.PortConfig == null)
                                {
                                    this.loadBalancerConfiguration.PortConfig = new PortConfig();
                                }
                                this.loadBalancerConfiguration.PortConfig.Protocol = value;                              
                            }                             
                        };
                    Func<string> autoParamNameGetter = () => ParametersViewModel.VMRolePrefix + PropertyNames.LoadBalancerPortConfigProtocol;
                    ViewDefParamInfo viewDefParamInfo = new ViewDefParamInfo
                    {
                        ViewDefParameterType = ViewDefParameterType.Option,
                        Options = new List<string>(Enum.GetNames(typeof(PortCfgProtocol))),
                        DefaultEnglishLabelText = "Load balancer port configuration protocol"
                    };

                    this.protocol = new EnumParameterizableProperty(
                        PropertyNames.LoadBalancerPortConfigProtocol,
                        paramValueGetter,
                        paramValueSetter,
                        autoParamNameGetter,
                        ParameterType.String,
                        "Load balancer port configuration protocol",
                        this.resourceDefinitionViewModel.ResourceDefinitionParametersViewModel,                    
                        typeof(PortCfgProtocol),
                        this.loadBalancerConfiguration != null,
                        viewDefParamInfo);
                }
                return this.protocol;
            }
        }

        /// <summary>
        /// FrontEndPort
        /// </summary>
        public IntParameterizableProperty LoadBalancerFrontEndPort
        {
            get
            {
                if (this.frontEndPort == null)
                {                   
                    Func<string> paramValueGetter = () =>
                    {
                        if (this.loadBalancerConfiguration == null)
                        {
                            return null;
                        }
                        if (this.loadBalancerConfiguration.PortConfig == null)
                        {
                            this.loadBalancerConfiguration.PortConfig = new PortConfig();
                        }
                        return this.loadBalancerConfiguration.PortConfig.FrontEndPort;
                    };        
                     
                    Action<string> paramValueSetter = delegate(string value)
                        {
                            if (this.loadBalancerConfiguration != null)
                            {
                                if (this.loadBalancerConfiguration.PortConfig == null)
                                {
                                    this.loadBalancerConfiguration.PortConfig = new PortConfig();
                                }
                                this.loadBalancerConfiguration.PortConfig.FrontEndPort = value;                              
                            }                               
                        };
                    Func<string> autoParamNameGetter = () => ParametersViewModel.VMRolePrefix + PropertyNames.LoadBalancerFrontEndPort;
                    ViewDefParamInfo viewDefParamInfo = new ViewDefParamInfo
                    {
                        ViewDefParameterType = ViewDefParameterType.Number,
                        DefaultInitialValue = "443",
                        DefaultEnglishLabelText = "Load balancer front end port"
                    };

                    this.frontEndPort= new IntParameterizableProperty(
                       PropertyNames.LoadBalancerFrontEndPort,
                       paramValueGetter,
                       paramValueSetter,
                       autoParamNameGetter,
                       ParameterType.Int,
                       "Load balancer front end port",
                       this.resourceDefinitionViewModel.ResourceDefinitionParametersViewModel,
                       this.loadBalancerConfiguration != null,
                       viewDefParamInfo);
                }
                return this.frontEndPort;
            }
        }

        /// <summary>
        /// BackEndPort
        /// </summary>
        public IntParameterizableProperty LoadBalancerBackEndPort
        {
            get
            {
                if (this.backEndPort == null)
                {                   
                    Func<string> paramValueGetter = () =>
                    {
                        if (this.loadBalancerConfiguration == null)
                        {
                            return null;
                        }
                        if (this.loadBalancerConfiguration.PortConfig == null)
                        {
                            this.loadBalancerConfiguration.PortConfig = new PortConfig();
                        }
                        return this.loadBalancerConfiguration.PortConfig.BackEndPort;
                    };                   
                    Action<string> paramValueSetter = delegate(string value)
                        {
                            if (this.loadBalancerConfiguration != null)
                            {
                                if (this.loadBalancerConfiguration.PortConfig == null)
                                {
                                    this.loadBalancerConfiguration.PortConfig = new PortConfig();
                                }
                                this.loadBalancerConfiguration.PortConfig.BackEndPort = value;                                
                            }    
                            
                        };
                    Func<string> autoParamNameGetter = () => ParametersViewModel.VMRolePrefix + PropertyNames.LoadBalancerBackEndPort;
                    ViewDefParamInfo viewDefParamInfo = new ViewDefParamInfo
                    {
                        ViewDefParameterType = ViewDefParameterType.Number,
                        DefaultInitialValue = "443",
                        DefaultEnglishLabelText = "Load balancer back end port"
                    };

                    this.backEndPort = new IntParameterizableProperty(
                       PropertyNames.LoadBalancerBackEndPort,
                       paramValueGetter,
                       paramValueSetter,
                       autoParamNameGetter,
                       ParameterType.Int,
                       "Load balancer back end port",
                       this.resourceDefinitionViewModel.ResourceDefinitionParametersViewModel,
                       this.loadBalancerConfiguration != null,
                       viewDefParamInfo);
                }
                return this.backEndPort;
            }
        }


        public bool LoadBalancerProbeEnabled
        {
            get { return this.loadBalancerConfiguration != null && this.loadBalancerConfiguration.Probe != null; }
            set
            {
                if (value)
                {
                    this.LoadBalancerProbeIntervalInSeconds.IsRequired = true;
                    this.LoadBalancerProbeIntervalInSeconds.PropertyValue = null;
                    this.LoadBalancerProbeProtocol.IsRequired = true;
                    this.LoadBalancerProbeProtocol.PropertyValue = null;
                    this.LoadBalancerProbePort.IsRequired = true;
                    this.LoadBalancerProbePort.PropertyValue = null;
                    this.LoadBalancerProbeMaxRetryCount.IsRequired = true;
                    this.LoadBalancerProbeMaxRetryCount.PropertyValue = null;
                    this.LoadBalancerProbeRequestPath.IsRequired = false;
                    this.LoadBalancerProbeRequestPath.PropertyValue = null;
                }
                else
                {
                    this.LoadBalancerProbeIntervalInSeconds.IsRequired = false;
                    this.LoadBalancerProbeIntervalInSeconds.Cleanup();
                    this.LoadBalancerProbeProtocol.IsRequired = false;
                    this.LoadBalancerProbeProtocol.Cleanup();
                    this.LoadBalancerProbePort.IsRequired = false;
                    this.LoadBalancerProbePort.Cleanup();
                    this.LoadBalancerProbeMaxRetryCount.IsRequired = false;
                    this.LoadBalancerProbeMaxRetryCount.Cleanup();
                    this.LoadBalancerProbeRequestPath.IsRequired = false;
                    this.LoadBalancerProbeRequestPath.Cleanup();
                    this.loadBalancerConfiguration.Probe = null;
                }
            }
        }

        public IntParameterizableProperty LoadBalancerProbeIntervalInSeconds
        {
            get
            {
                if (this.probeIntervalInSeconds == null)
                {                                       
                    Func<string> paramValueGetter = () =>
                    {
                        if (this.loadBalancerConfiguration == null)
                        {
                            return null;
                        }
                        return this.loadBalancerConfiguration.Probe == null ? null : this.loadBalancerConfiguration.Probe.ProbeIntervalInSeconds;
                    };                          
                    Action<string> paramValueSetter = delegate(string value)
                        {
                            if (this.loadBalancerConfiguration != null)
                            {
                                if (this.loadBalancerConfiguration.Probe == null)
                                {
                                    this.loadBalancerConfiguration.Probe = new Probe();
                                }
                                this.loadBalancerConfiguration.Probe.ProbeIntervalInSeconds = value;
                            }                           
                        };
                    Func<string> autoParamNameGetter = () => PropertyNames.LoadBalancerProbeIntervalInSeconds;
                    ViewDefParamInfo viewDefParamInfo = new ViewDefParamInfo
                    {
                        ViewDefParameterType = ViewDefParameterType.Number,
                        DefaultInitialValue = "3",
                        DefaultEnglishLabelText = "Load balancer probe interval in seconds"
                    };

                    this.probeIntervalInSeconds = new IntParameterizableProperty(
                       PropertyNames.LoadBalancerProbeIntervalInSeconds,
                       paramValueGetter,
                       paramValueSetter,
                       autoParamNameGetter,
                       ParameterType.Int,
                       "Load Balancer Probe Interval in seconds",
                       this.resourceDefinitionViewModel.ResourceDefinitionParametersViewModel,
                       this.LoadBalancerProbeEnabled,
                       viewDefParamInfo);
                }
                return this.probeIntervalInSeconds;
            }
        }


        /// <summary>
        /// LbCfgProbeProtocol
        /// </summary>
        public EnumParameterizableProperty LoadBalancerProbeProtocol
        {
            get
            {
                if (this.probeProtocol == null)
                {                   
                    Func<string> paramValueGetter = () =>
                    {
                        if (this.loadBalancerConfiguration == null)
                        {
                            return null;
                        }
                        return this.loadBalancerConfiguration.Probe == null ? null : this.loadBalancerConfiguration.Probe.Protocol;
                    };  
                       
                    Action<string> paramValueSetter = delegate(string value)
                        {
                            if (this.loadBalancerConfiguration != null)
                            {
                                if (this.loadBalancerConfiguration.Probe == null)
                                {
                                    this.loadBalancerConfiguration.Probe = new Probe();
                                }
                                this.loadBalancerConfiguration.Probe.Protocol = value;
                            }                            
                        };
                    Func<string> autoParamNameGetter = () => ParametersViewModel.VMRolePrefix + PropertyNames.LoadBalancerPortConfigProtocol;
                    ViewDefParamInfo viewDefParamInfo = new ViewDefParamInfo
                    {
                        ViewDefParameterType = ViewDefParameterType.Option,
                        Options = new List<string>(Enum.GetNames(typeof(LbCfgProbeProtocol))),
                        DefaultEnglishLabelText = "Load balancer probe protocol"
                    };

                    this.probeProtocol = new EnumParameterizableProperty(
                        PropertyNames.LoadBalancerProbeProtocol,
                        paramValueGetter,
                        paramValueSetter,
                        autoParamNameGetter,
                        ParameterType.String,
                        "Load Balancer Probe Protocol",
                        this.resourceDefinitionViewModel.ResourceDefinitionParametersViewModel,
                        typeof(LbCfgProbeProtocol),
                        this.LoadBalancerProbeEnabled,
                        viewDefParamInfo);
                }
                return this.probeProtocol;
            }
        }


        /// <summary>
        /// LoadBalancerProbePort
        /// </summary>
        public IntParameterizableProperty LoadBalancerProbePort
        {
            get
            {
                if (this.probePort == null)
                {                   
                    Func<string> paramValueGetter = () =>
                    {
                        if (this.loadBalancerConfiguration == null)
                        {
                            return null;
                        }
                        return this.loadBalancerConfiguration.Probe == null ? null : this.loadBalancerConfiguration.Probe.Port;
                    }; 
                      
                    Action<string> paramValueSetter = delegate(string value)
                        {
                            if (this.loadBalancerConfiguration != null)
                            {
                                if (this.loadBalancerConfiguration.Probe == null)
                                {
                                    this.loadBalancerConfiguration.Probe = new Probe();
                                }
                                this.loadBalancerConfiguration.Probe.Port = value;
                            }                            
                        };
                    Func<string> autoParamNameGetter = () => ParametersViewModel.VMRolePrefix + PropertyNames.LoadBalancerProbePort;
                    ViewDefParamInfo viewDefParamInfo = new ViewDefParamInfo
                    {
                        ViewDefParameterType = ViewDefParameterType.Number,
                        DefaultInitialValue = "80",
                        DefaultEnglishLabelText = "Load balancer probe port"
                    };

                    this.probePort = new IntParameterizableProperty(
                       PropertyNames.LoadBalancerProbePort,
                       paramValueGetter,
                       paramValueSetter,
                       autoParamNameGetter,
                       ParameterType.Int,
                       "Load balancer probe port",
                       this.resourceDefinitionViewModel.ResourceDefinitionParametersViewModel,
                       this.LoadBalancerProbeEnabled,
                       viewDefParamInfo);
                }
                return this.probePort;
            }
        }

        /// <summary>
        /// LoadBalancerProbeMaxRetryCount
        /// </summary>
        public IntParameterizableProperty LoadBalancerProbeMaxRetryCount
        {
            get
            {
                if (this.probeMaxRetryCount == null)
                {                  
                    Func<string> paramValueGetter = () =>
                    {
                        if (this.loadBalancerConfiguration == null)
                        {
                            return null;
                        }
                        return this.loadBalancerConfiguration.Probe == null ? null : this.loadBalancerConfiguration.Probe.MaxRetryCount; 
                    }; 
                        
                    Action<string> paramValueSetter = delegate(string value)
                        {
                            if (this.loadBalancerConfiguration != null)
                            {
                                if (this.loadBalancerConfiguration.Probe == null)
                                {
                                    this.loadBalancerConfiguration.Probe = new Probe();
                                }
                                this.loadBalancerConfiguration.Probe.MaxRetryCount = value;
                            }                            
                        };
                    Func<string> autoParamNameGetter = () => ParametersViewModel.VMRolePrefix + PropertyNames.LoadBalancerProbeMaxRetryCount;
                    ViewDefParamInfo viewDefParamInfo = new ViewDefParamInfo
                    {
                        ViewDefParameterType = ViewDefParameterType.Number,
                        DefaultInitialValue = "2",
                        DefaultEnglishLabelText = "Load balancer probe port max retry count"
                    };

                    this.probeMaxRetryCount = new IntParameterizableProperty(
                       PropertyNames.LoadBalancerProbeMaxRetryCount,
                       paramValueGetter,
                       paramValueSetter,
                       autoParamNameGetter,
                       ParameterType.Int,
                       "Load balancer probe port max retry count",
                       this.resourceDefinitionViewModel.ResourceDefinitionParametersViewModel,
                       this.LoadBalancerProbeEnabled,
                       viewDefParamInfo);
                }
                return this.probeMaxRetryCount;
            }
        }

        public StringParameterizableProperty LoadBalancerProbeRequestPath
        {
            get
            {
                if (this.probeRequestPath == null)
                {
                    Func<string> paramValueGetter = () =>
                    {
                        if (this.loadBalancerConfiguration == null)
                        {
                            return null;
                        }
                        return this.loadBalancerConfiguration.Probe == null ? null : this.loadBalancerConfiguration.Probe.RequestPath; 
                    }; 
                        
                    Action<string> paramValueSetter = delegate(string value)
                    {
                        if (this.loadBalancerConfiguration != null)
                        {
                            if (this.loadBalancerConfiguration.Probe == null)
                            {
                                this.loadBalancerConfiguration.Probe = new Probe();
                            }
                            this.loadBalancerConfiguration.Probe.RequestPath = value;
                        }                       
                    };
                    Func<string> autoParamNameGetter = () => ParametersViewModel.VMRolePrefix + PropertyNames.LoadBalancerProbeRequestPath;
                    ViewDefParamInfo viewDefParamInfo = new ViewDefParamInfo
                    {
                        ViewDefParameterType = ViewDefParameterType.String,                       
                        DefaultEnglishLabelText = "Load balancer probe request path"
                    };

                    this.probeRequestPath = new StringParameterizableProperty(
                        PropertyNames.LoadBalancerProbeRequestPath,
                        paramValueGetter,
                        paramValueSetter,
                        autoParamNameGetter,
                        ParameterType.String,
                        "Load balancer probe request path",
                        this.resourceDefinitionViewModel.ResourceDefinitionParametersViewModel,
                        this.LoadBalancerProbeEnabled,
                        viewDefParamInfo);
                }
                return this.probeRequestPath;
            }
        }

        public string this[string propertyName]
        {
            get
            {
                string error = null;
                switch (propertyName)
                {
                    case PropertyNames.LoadBalancerFrontEndPort:
                        if (this.frontEndPort != null && this.frontEndPort.PropertyValue != null)
                        {
                            int fport;
                            if (int.TryParse(this.frontEndPort.PropertyValue, out fport))
                            {
                                if (fport < 0 || fport > System.Net.IPEndPoint.MaxPort)
                                {
                                    error = "Front End Port Value is invalid. Must be between 0 and 65535";
                                }
                                else
                                {
                                    int bport;
                                    if (this.backEndPort != null &&
                                        int.TryParse(this.backEndPort.PropertyValue, out bport))
                                    {
                                        if (fport != bport)
                                        {
                                            error =
                                                "Different Values For FrontEnd And BackEnd Port are not supported in Windows Azure Pack 2012 R2 release. They must be identical.";
                                        }
                                    }

                                }
                            }
                        }
                        break;
                    case PropertyNames.LoadBalancerBackEndPort:
                        if (this.backEndPort != null && this.backEndPort.PropertyValue != null)
                        {
                            int bport;
                            if (int.TryParse(this.frontEndPort.PropertyValue, out bport))
                            {
                                if (bport < 0 || bport > System.Net.IPEndPoint.MaxPort)
                                {
                                    error = "Back End Port Value is invalid. Must be between 0 and 65535";
                                }
                                else
                                {
                                    int fport;
                                    if (this.frontEndPort != null &&
                                        int.TryParse(this.frontEndPort.PropertyValue, out fport))
                                    {
                                        if (fport != bport)
                                        {
                                            error =
                                                "Different Values For FrontEnd And BackEnd Port are not supported in Windows Azure Pack 2012 R2 release. They must be identical.";
                                        }
                                    }

                                }
                            }
                        }
                        break;
                    case PropertyNames.LoadBalancerProbePort:
                        if (this.probePort != null && this.probePort.PropertyValue != null)
                        {
                            int pport;
                            if (int.TryParse(this.probePort.PropertyValue, out pport))
                            {
                                if (pport < 0 || pport > System.Net.IPEndPoint.MaxPort)
                                {
                                    error = "Probe Port Value is invalid. Must be between 0 and 65535";
                                }                               
                            }
                        }
                        break;
                }
                return error;
            }
        }

        public string Error { get { return null; } }
    }
}
